package com.easyj.admin.edu.serviceimpl;

import java.util.List;
import java.util.Date;
import java.util.HashMap;

import org.activiti.api.process.model.builders.ProcessPayloadBuilder;
import org.activiti.api.process.runtime.ProcessRuntime;
import org.activiti.api.task.model.Task;
import org.activiti.api.task.model.builders.TaskPayloadBuilder;
import org.activiti.api.task.runtime.TaskRuntime;
import org.activiti.engine.HistoryService;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.history.HistoricProcessInstance;
import org.activiti.engine.history.HistoricProcessInstanceQuery;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import com.easyj.admin.activiti.service.TaskCommentService;
import com.easyj.admin.activiti.utils.ProcessUtils;
import com.easyj.admin.activiti.vo.SimpleApproveVO;
import com.easyj.admin.db.mapper.LeaveMapper;
import com.easyj.base.exception.*;
import com.easyj.base.security.SimpleUser;
import com.easyj.base.security.service.SecurityUtil;
import com.easyj.base.enums.MutiApplyStatusEnum;
import com.easyj.base.common.page.Page;
import com.easyj.admin.db.model.Leave;
import com.easyj.admin.db.model.LeaveQO;
import com.easyj.admin.db.model.TaskComment;
import com.easyj.admin.edu.service.LeaveService;

/**
 * 使用岗位作为候选人
 * @author hjf
 *
 */

@Service
public class LeaveServiceImpl implements LeaveService{

   
	@Autowired
	private  LeaveMapper leaveMapper;
	

	@Autowired
    private ProcessRuntime processRuntime;
	
	@Autowired
    private TaskRuntime taskRuntime;
	
	@Autowired
	private RuntimeService runtimeService;
	
	@Autowired
	private TaskService taskService;
	
	@Autowired
	private TaskCommentService taskCommentService;
	
	@Autowired
	private  HistoryService historyService;
	
	  	
	public Page<Leave> findPage(LeaveQO filter){
	    Long total=leaveMapper.countByExample(filter);
		List<Leave> rows=null;
		if(total>0l){
			filter.getPage().resetOffsetByTotal(total);
		    rows= leaveMapper.selectByExample(filter);
		}
		
		Page<Leave> rtn=new Page<Leave>(rows,total,filter.getPage());
		return rtn;
	}
	
	public List<TaskComment> findCommentsById(Long entityId){
		HistoricProcessInstanceQuery query = historyService.createHistoricProcessInstanceQuery();
		query.processInstanceBusinessKey(entityId.toString());
		query.processDefinitionKey(ProcessDefKey);
		HistoricProcessInstance processInstance =  query.singleResult();
		List<TaskComment> rtn=taskCommentService.findByProcInstId(processInstance.getId());
		return rtn;
	}
	


   	public List<Leave> findList(LeaveQO filter){
        return leaveMapper.selectByExample(filter);
    }
	public long count(LeaveQO filter){
	     return leaveMapper.countByExample(filter);
	}	


	public Leave findById(Long id){
		Leave entity= leaveMapper.selectByPrimaryKey(id);
		return entity;
	}
	
	
	@Transactional
	public int  apply(Leave entity) throws EasyjException{
		entity.setApplyTime(new Date());
		SimpleUser usr=SecurityUtil.getOperator();
		entity.setApplicantId(usr.getId());
		entity.setDeptId(usr.getDepartmentId());
		entity.setStatus(MutiApplyStatusEnum.WAITING.getKey());	
		entity.setApplyTime(new Date());
		int rtn= leaveMapper.insert(entity);
		
		//start process,set businessKey=entity.id
		String businessKey = entity.getId().toString(); //业务key,
		
		HashMap<String, Object> varmap=new HashMap<String, Object>(5);
		varmap.put("pass", false); //是否审批通过
		varmap.put("days", entity.getTotalDays().doubleValue());  //请假天数
        
		processRuntime.start(ProcessPayloadBuilder
	                        .start()
	                        .withProcessDefinitionKey(ProcessDefKey)
	                        .withName(entity.getApplyName())
	                        .withBusinessKey(businessKey)
	                        .withVariables(varmap)
	                        .build());
		return rtn;
	}
	
	@Transactional
	public void approve(SimpleApproveVO approveVO) throws EasyjException{
		Task task=taskRuntime.task(approveVO.getTaskId());
		if(!task.getBusinessKey().equals(approveVO.getEntityId().toString())) {
			throw new  ValidateException("数据不符合要求！");
		}
		
		Leave entity=leaveMapper.selectByPrimaryKey(approveVO.getEntityId());
		if(entity.getStatus().intValue()!=MutiApplyStatusEnum.WAITING.getKey()){
			throw new  ValidateException("状态不是‘等待审批’！");
		}		
		
		//update entity
		if(approveVO.isPassed()){
		    entity.setStatus(MutiApplyStatusEnum.WaitAudit.getKey());
	    }else {
	    	entity.setStatus(MutiApplyStatusEnum.REJECT.getKey());
	    }
		
		entity.setApproveComment(approveVO.getComment());
		entity.setApproveId(approveVO.getApproveUserId());
		entity.setApproveTime(new Date());		
		leaveMapper.updateByPrimaryKeySelective(entity);
		
		
		//加上审批意见
		ProcessUtils.addComment(task,SecurityUtil.getOperatorId().toString(), approveVO.isPassed(), approveVO.getComment());		
         //流程定义 指定了 assginee 不需要 claim
		if(StringUtils.isBlank(task.getAssignee())){
			taskRuntime.claim(
               TaskPayloadBuilder.claim().withTaskId(approveVO.getTaskId()).build());
		}
		
	     //用原来的taskService	
		taskService.setVariable(approveVO.getTaskId(), "pass", approveVO.isPassed());
		taskService.complete(approveVO.getTaskId());
		
	}
	
	
	@Transactional(rollbackFor=Exception.class)
	public void auditApply(SimpleApproveVO approveVO) throws EasyjException{
		Task task=taskRuntime.task(approveVO.getTaskId());
		if(!task.getBusinessKey().equals(approveVO.getEntityId().toString())) {
			throw new  ValidateException("数据不符合要求！");
		}
		Leave entity=leaveMapper.selectByPrimaryKey(approveVO.getEntityId());
		if(entity.getStatus().intValue()!=MutiApplyStatusEnum.WaitAudit.getKey()){
			throw new  ValidateException("状态不是‘"+MutiApplyStatusEnum.WaitAudit.getText()+"’！");
		}
					
		
		//update entity
		if(approveVO.isPassed()){
		    entity.setStatus(MutiApplyStatusEnum.PASSED.getKey());
	    }else {
	    	entity.setStatus(MutiApplyStatusEnum.REJECT.getKey());
	    }
		
		entity.setApproveComment(approveVO.getComment());
		entity.setApproveId(approveVO.getApproveUserId());
		entity.setApproveTime(new Date());		
		leaveMapper.updateByPrimaryKeySelective(entity);
		
		//加上审批意见
		ProcessUtils.addComment(task,SecurityUtil.getOperatorId().toString(), approveVO.isPassed(), approveVO.getComment());		
		if(StringUtils.isBlank(task.getAssignee())){   
		taskRuntime.claim(
               TaskPayloadBuilder.claim().withTaskId(approveVO.getTaskId()).build());
		}
		taskRuntime.complete(
                TaskPayloadBuilder.complete()
                        .withTaskId(approveVO.getTaskId()) 
                        .build());  
				
	}
	
	
	@Transactional
	public int  updateEntity(Leave entity) throws EasyjException{
		
	    Leave find=leaveMapper.selectByPrimaryKey(entity.getId());
		if(find.getApplicantId().longValue()!=SecurityUtil.getOperatorId().longValue()) {
			throw new  ValidateException("非法操作！");
		}
		if(find.getStatus()!=MutiApplyStatusEnum.WAITING.getKey()) {
			throw new  ValidateException("非法操作,只能修改‘等待审批’的申请！");
		}
		entity.setStatus(find.getStatus());	
		int rtn= leaveMapper.updateByPrimaryKey(entity);
		return rtn;
	}



	/**
     * 按实体ID取消流程
	 */ 
	@Transactional(rollbackFor=Exception.class)
	public int  cancel(Long id) throws EasyjException{
		Leave find=leaveMapper.selectByPrimaryKey(id);
		if(find.getApplicantId().longValue()!=SecurityUtil.getOperatorId().longValue()) {
			throw new  ValidateException("非法操作！");
		}
		if(find.getStatus()!=MutiApplyStatusEnum.WAITING.getKey()) {
			throw new  ValidateException("只能取消‘等待审批’的申请！");
		}
		
		find.setStatus(MutiApplyStatusEnum.CANCEl.getKey());
		find.setApproveTime(new Date()); //共用
		
		int rtn= leaveMapper.updateByPrimaryKey(find);
		
		
		//取消,delete流程实例 
		org.activiti.engine.runtime.ProcessInstance processInstance = runtimeService.createProcessInstanceQuery().processInstanceBusinessKey(find.getId().toString(), ProcessDefKey).active().singleResult();
		runtimeService.deleteProcessInstance(processInstance.getId(), "申请人取消");
		
		return rtn;
	}
   


}
